--
-- @Author:      feilong
-- @DateTime:    2019-04-23 10:05:48
-- @Description: 会话管理

local skynet = require "skynet"


local SessionManager = class("SessionManager")


--初始化
function SessionManager:ctor(message_dispatch)
    
    -- local session = {
    --     session_id = nil,    --socket句柄
    --     contype = nil,       --socket类型
    --     service = nil,       --socket服务
    --     addr = nil,          --ip地址
    --     time = nil,          --计时器，长时间没反应删除socket
    --     sid = nil,           --消息验证id
    --     user_id = nil,       --用户id
    -- }
    self.message_dispatch = message_dispatch
    self.server_name = skynet.getenv("server_name")
    self.session_list = {}   --存储用户标识user_id

    --socket状态消息
    self.socket_handler = {}
    self.socket_handler.open = handler(self,self.openSocket)
    self.socket_handler.close = handler(self,self.closeSocket)
    self.socket_handler.error = handler(self,self.errorSocket)
    self.socket_handler.warning = handler(self,self.warningSocket)
    self.socket_handler.data = handler(self,self.dataSocket)    

    self:register()
end

function SessionManager:register()
    self.message_dispatch:registerSelf('socket', handler(self, self.dispatch))
    
end    

--socket相关状态消息
function SessionManager:dispatch(source, cmd, ... )
    local func = self.socket_handler[cmd]   
    if func then
        return func(source, ...)
    end
end

--- 用户连接
--- @param fd @class number 连接标识符
--- @param addr @class string 连接地址
--- @param contype@class string 连接类型
function SessionManager:openSocket(gate, fd, addr, contype)
    debug_log("___new client fd:" ..fd .." from :".. addr)
    -- self.service_index = fd % #self.gate_services + 1
    -- local gate_service = self.gate_services[self.service_index]
    local addr = string.split(addr, ':')
    local ip = addr[1]  

    local session = {
        session_id = fd,        --socket句柄
        contype = contype,      --连接类型,socket websocket
        addr = ip,              --ip地址
        time = os.time(),       --计时器，长时间没反应删除socket
        sid = 1,                --消息验证id
        user_id = nil,          --用户id
        gate = gate,
    }
    self:addSession(session)

    skynet.call(gate, "lua", "forward", fd)   

end

--socket关闭
function SessionManager:closeSocket(watchdog, fd)
    debug_log("####client socket close", fd)
    self:disconnect(fd)
    -- self.session_list[fd] = nil
end

--socket错误
function SessionManager:errorSocket(watchdog, fd, msg)
    -- print("####client socket error", fd, msg)
    debug_log("####client socket error", fd, msg)
    self:disconnect(fd)
    -- self.session_list[fd] = nil
end

function SessionManager:warningSocket(watchdog, fd, size)
    -- debug_log("client socket warning", fd, size)
end

function SessionManager:dataSocket(watchdog, fd, msg)
    debug_log("####client socket data", fd, msg)

end







--
function SessionManager:start()
    self.node_message = global.node_message
    self.user_manager = global.user_manager
end

--重置数据
function SessionManager:reset()
    self.session_list = {}
end

--添加会话
function SessionManager:addSession(session)

    self.session_list[session.session_id] = session
end

--移除会话
function SessionManager:removeSession(session_id)

    self.session_list[session_id] = nil
end

--绑定会话
function SessionManager:bindSession(session_id, user_id)
    if self.session_list[session_id] then
        self.session_list[session_id].user_id = user_id
        return true
    end
    return false
end

--解除绑定会话
function SessionManager:unbindSession(session_id)
    if self.session_list[session_id] then
        self.session_list[session_id].user_id = nil
        return true
    end
    return false
end

--获取所有会话
function SessionManager:getSessionList()
    return self.session_list
end

--获取会话
function SessionManager:getSession(session_id)
    return self.session_list[session_id]
end

function SessionManager:disconnect(session_id)
    local session = self.session_list[session_id]
    if not session then 
        return
    end
    local user_id = session.user_id
    self:removeSession(session_id)
    --通知断线
    if user_id then
        local user = self.user_manager:getUser(user_id)
        local server_list = user:getServerList()
        for k, v in pairs(server_list) do 
            self.node_message:sendNodeManager(v, "disconnect", {user_id=user_id})
        end
        self.user_manager:removeUser(user_id)   
    end
end



return SessionManager